/*
** Copyright (c) 2008 Mobile GCalendarManager
**
** Permission is hereby granted, free of charge, to any person
** obtaining a copy of this software and associated documentation
** files (the "Software"), to deal in the Software without
** restriction, including without limitation the rights to use,
** copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the
** Software is furnished to do so, subject to the following
** conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
** OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
** HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
** OTHER DEALINGS IN THE SOFTWARE.
*/

/**
 *
 */
package au.edu.mq.comp.itec800.mgc.ui.cli.commands;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;

import org.apache.log4j.Logger;

import au.edu.mq.comp.itec800.mgc.ui.cli.Context;
import au.edu.mq.comp.itec800.mgc.ui.cli.ICommand;


/**
 * @author Laurent Malvert [laurent.malvert@students.mq.edu.au]
 *
 */
public class CommandLoader
{
  private static final Logger logger  = Logger.getLogger(CommandLoader.class);

  private static HashMap<String, Class<? extends ICommand>> classes   = new HashMap<String, Class<? extends ICommand>>(6);
  private static HashMap<String, Method>                    invokers  = new HashMap<String, Method>(6);


  /*
   * -loads the ICommand implementation classes from the Context enum type
   * -generates the required method invokers for each class for later use
   */
  static
  {
    for (final Context ctxt : Context.values())
    {
      final Class<? extends ICommand> clazz = ctxt.getCommanderClass();

      if (clazz != null)
      {
        classes.put(clazz.getName(), clazz);
        invokers.put(clazz.getName(), getInitMethod(clazz));
      }
    }
  }

  public static Method    getInitMethod(final Class<? extends ICommand> clazz)
  {
    Method                m = null;

    try
    {
      m = clazz.getDeclaredMethod("valueOf", String.class);
    }
    catch (final SecurityException e)
    {
      logger.error(e.getMessage(), e);
    }
    catch (final NoSuchMethodException e)
    {
      logger.error(e.getMessage(), e);
    }
    return (m);
  }

  public static ICommand  load(final Class<? extends ICommand> clazz,
                               final String command)
  {
    ICommand              cmd = null;

    try
    {
      cmd = (ICommand) invokers.get(clazz.getName()).invoke(null, command);
    }
    catch (final IllegalArgumentException e)
    {
      cmd = MainCommand.noop;
    }
    catch (final IllegalAccessException e)
    {
      logger.error(e.getMessage(), e);
    }
    catch (final InvocationTargetException e)
    {
      logger.error(e.getMessage(), e);
    }
    return (cmd);
  }
}
